package com.dkm.websocket;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.json.JSONObject;
import org.springframework.stereotype.Component;

import com.dkm.entity.MessagePojo;

//配置websocket地址（端点）
@ServerEndpoint("/communicate/{userno}")
@Component
public class CommunicateWebSocket {
		//记录在线人数
		private static Integer onlineCount=0;
		
		//存储连接对象的集合
		//private static CopyOnWriteArrayList<MyWebSocket> webSocketSet=new CopyOnWriteArrayList<MyWebSocket>();
		private static ConcurrentHashMap<String, CommunicateWebSocket> webSocketSet=new ConcurrentHashMap<String, CommunicateWebSocket>();
		
		//用户id
		private String userno="";
		
		
		//当前用户
		private Session session;
		/**
		 * 在客服端的websocket时间和方法，
		 * 在服务端有相对应的注解来表示
		 * 
		 */
		
		//当建立连接时触发
		@OnOpen
		public void onOpen(@PathParam(value = "userno") String userno,Session session) {
			System.out.println("用户编号》"+userno+"加入");
			this.userno = userno;//接收到发送消息的人员编号
			this.session=session;
			//加入用户集合中
			webSocketSet.put(userno, this);
			//在线人数加1
			addOnlineCount();
			System.out.println("有连接加入！当前在线人数："+getOnlineCount());
		}
		
		/**
		 * 当收到客户端消息时触发
		 * @param session 可选的参数
		 * @param message 客户端发送过来的消息
		 */
		@OnMessage
		public void onMessage(Session session,String  message) {
			System.out.println("客服端发来消息："+message);
			//群发消息
			//遍历出当前连接的websocket对象
//			if(3<2) {
//		        //群发消息
//				sendAll(message);
//			}else {
//	            //给指定的人发消息
//				sendToUser(message);
//			}
		}
		/**
		 * 给指定的人发消息
		 * @param message
		 */
		public void sendToUser(MessagePojo message) {
			//创建转换json工具对象
	        net.sf.json.JSONObject jsonObject=new net.sf.json.JSONObject();
	        //将消息对象存入工具类中
	        jsonObject.put("message", message);
	        
	        String sendUserno=message.getReceiver_id();//接收人id
			//String sendUserno=message.split("[|]")[2];//要发送给消息的人
			//String sendMessage=message.split("[|]")[1];//消息内容
			String now = this.getNowTime();
			try {
				//判断推送给的用户是否在线
				if(webSocketSet.get(sendUserno)!=null) {
					webSocketSet.get(sendUserno).sendMessage(jsonObject.toString());
				System.out.println("jsonObject.toString()"+jsonObject.toString());
				}else {
					System.out.println("当前用户不在线");
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			};
		}
		
		/**
		 * 给所有人发消息（广播）
		 * @param message
		 */
		public void sendAll(MessagePojo message) {
			//创建转换json工具对象
	        net.sf.json.JSONObject jsonObject=new net.sf.json.JSONObject();
	        //将消息对象存入工具类中
	        jsonObject.put("message", message);
	        //System.out.println("message>"+message);
	        
			String now=this.getNowTime();
			//String sendMessage = message.split("[|]")[0];
			//遍历HashMap
			for (String key : webSocketSet.keySet()) {
				
				try {
					//判断接收用户是否是当前发消息的用户
					if(!message.getSender_id().equals(key)) {
						webSocketSet.get(key).sendMessage(jsonObject.toString());
						System.out.println("key>"+key);
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		}
		
		/**
		 * 当连接关闭时触发
		 */
		@OnClose
		public void onClose() {
			if(!"".equals(userno)) {
				//移除用户
				webSocketSet.remove(userno);
				//在线人数减1
				subOnlineCount();
				System.out.println("有一连接关闭，当前在线人数："+getOnlineCount());
			}
		}
		
		/**
		 * 发生异常时触发
		 * throwable异常（必须）
		 * @param throwable
		 */
		@OnError
		public void onError(Throwable throwable) {
			System.out.println("连接异常，已断开。。。");
			throwable.printStackTrace();
		}
		
		/**
		 * 这个方法与上面几个方法不一样。没有用注解，是根据自己需要添加的方法。
		 * 服务端向客服端发送消息
		 * @param message
		 * @throws IOException
		 */
		public void sendMessage(String message) throws IOException {
			//getBasicRemote()阻塞式   getAsyncRemote()非阻塞式
			this.session.getBasicRemote().sendText(message);
	        //this.session.getAsyncRemote().sendText(message);
		}
		
	    public static synchronized int getOnlineCount() {
	        return onlineCount;
	    }
		
		/**
		 * 在线人数加1
		 */
		public static synchronized void addOnlineCount() {
			CommunicateWebSocket.onlineCount++;
		}
		/**
		 * 在线人数减1
		 */
		public static synchronized void subOnlineCount() {
			CommunicateWebSocket.onlineCount--;
		}
		
		/**
		 * 获取当前时间
		 * @return
		 */
		private String getNowTime() {
			Date date=new Date();
			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			
			return sdf.format(date);
		}
}
